package chapter11.eg6;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.CharsetUtil;
import java.util.concurrent.TimeUnit;

public class IdleStateHandlerInitializer extends ChannelInitializer<Channel> {

  @Override
  protected void initChannel(Channel ch) throws Exception {
    ChannelPipeline pipeline = ch.pipeline();
    pipeline.addLast(new IdleStateHandler(0, 0, 60, TimeUnit.SECONDS));
    pipeline.addLast(new HeartbeatHandler());
  }

  public static final class HeartbeatHandler extends ChannelInboundHandlerAdapter {

    private static final ByteBuf HEARTBEAT_SEQUENCE = Unpooled
        .unreleasableBuffer(Unpooled.copiedBuffer("HEARTBEAT",
            CharsetUtil.ISO_8859_1));

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
      if (evt instanceof IdleStateEvent) {
        ctx.writeAndFlush(HEARTBEAT_SEQUENCE.duplicate())
            .addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
      } else {
        super.userEventTriggered(ctx, evt);
      }
    }
  }
}
